class SpreadJSAgentClient {
    constructor() {
        this.ws = null;
        this.isConnected = false;
        this.currentExecutionId = null;
        this.sessionId = this.generateSessionId();
        this.init();
        this.setupEventListeners();
        this.connectWebSocket();
    }
    generateSessionId() {
        return 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
    }
    init() {
        // Initialize SpreadJS workbook
        const spread = new window.GC.Spread.Sheets.Workbook(document.getElementById('ss'));
        const sheet = spread.getActiveSheet();
        // Make workbook globally available
        window.GC = window.GC;
        window.workbook = spread;
        window.spread = spread;
        window.sheet = sheet;
        window.activeSheet = sheet;

        const arr = [
            ['Name', 'Age', 'City'],
            ['John', 25, 'New York'],
            ['Jane', 30, 'Los Angeles'],
            ['Jim', 35, 'Chicago']
        ];
        sheet.setArray(0, 0, arr);
        console.log('SpreadJS initialized successfully');
    }
    setupEventListeners() {
        const userInput = document.getElementById('userInput');
        const sendButton = document.getElementById('sendButton');
        sendButton.addEventListener('click', () => this.sendMessage());
        userInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                this.sendMessage();
            }
        });
    }
    connectWebSocket() {
        try {
            this.ws = new WebSocket('ws://localhost:3001');
            this.ws.onopen = () => {
                this.isConnected = true;
                this.updateStatus('已连接到服务器', 'connected');
                const sendButton = document.getElementById('sendButton');
                sendButton.disabled = false;
            };
            this.ws.onmessage = (event) => {
                this.handleServerMessage(JSON.parse(event.data));
            };
            this.ws.onclose = () => {
                this.isConnected = false;
                this.updateStatus('与服务器断开连接', 'error');
                const sendButton = document.getElementById('sendButton');
                sendButton.disabled = true;
            };
            this.ws.onerror = (error) => {
                console.error('WebSocket error:', error);
                this.updateStatus('连接错误', 'error');
            };
        }
        catch (error) {
            console.error('Failed to connect:', error);
            this.updateStatus('连接失败', 'error');
        }
    }
    updateStatus(message, type) {
        const statusElement = document.getElementById('status');
        statusElement.textContent = message;
        statusElement.className = `status ${type}`;
    }
    sendMessage() {
        const userInput = document.getElementById('userInput');
        const message = userInput.value.trim();
        if (!message || !this.isConnected || !this.ws) {
            return;
        }
        // Display user message
        this.addMessage(message, 'user');
        // Send to server
        this.ws.send(JSON.stringify({
            type: 'user_request',
            data: {
                message,
                sessionId: this.sessionId
            }
        }));
        // Clear input
        userInput.value = '';
        // Update status
        this.updateStatus('Agent 正在思考...', 'connecting');
    }
    handleServerMessage(message) {
        switch (message.type) {
            case 'agent_step':
                this.handleAgentStep(message.data);
                break;
            case 'agent_message':
                this.handleAgentMessage(message.data);
                break;
            case 'agent_complete':
                // 完成当前的流式消息
                this.finishCurrentAgentMessage();

                // 添加任务完成的消息
                const completeDiv = document.createElement('div');
                completeDiv.className = 'message system-message';
                completeDiv.innerHTML = `<strong>✅ 系统:</strong> 任务执行完成！`;
                this.addElementToChat(completeDiv);
                this.updateStatus('任务完成', 'connected');
                break;
            case 'error':
                this.addMessage(`错误: ${message.data.message}`, 'agent');
                this.updateStatus('发生错误', 'error');
                break;
        }
    }

            handleAgentMessage(messageData) {
        const { content, timestamp, stepId, sessionId } = messageData;

        // 获取当前活跃的AI消息div（最后一个agent-message）
        let messageDiv = this.getCurrentAgentMessage();

        if (!messageDiv) {
            // 创建新的AI回复消息
            messageDiv = document.createElement('div');
            messageDiv.className = 'message agent-message streaming';
            messageDiv.innerHTML = `<strong>🤖 SpreadJS Agent:</strong> <span class="content">${content}</span>`;
            this.addElementToChat(messageDiv);
        } else {
            // 流式追加内容
            const contentSpan = messageDiv.querySelector('.content');
            if (contentSpan) {
                contentSpan.textContent += content;
                // 滚动到底部以跟随内容
                this.scrollToBottom();
            }
        }

        this.updateStatus('Agent 正在思考...', 'connecting');
    }

    getCurrentAgentMessage() {
        // 获取最后一个正在流式输出的AI消息
        const agentMessages = document.querySelectorAll('.message.agent-message.streaming');
        return agentMessages.length > 0 ? agentMessages[agentMessages.length - 1] : null;
    }

    finishCurrentAgentMessage() {
        // 完成当前的流式消息
        const currentMessage = this.getCurrentAgentMessage();
        if (currentMessage) {
            currentMessage.classList.remove('streaming');
        }
    }

    scrollToBottom() {
        const chatMessages = document.getElementById('chatMessages');
        chatMessages.scrollTop = chatMessages.scrollHeight;
    }

    handleAgentStep(stepData) {
        const { step, output, timestamp, stepId } = stepData;

        // 工具调用开始时，完成当前的流式消息
        if (step === 'tools' && output.lastToolCall) {
            this.finishCurrentAgentMessage();
            const toolName = output.lastToolCall.name;

            // execute-spreadjs工具：只在有toolResult时才创建元素（避免重复）
            if (toolName === 'execute-spreadjs' && !output.toolResult) {
                // 跳过tool_start事件，等待tool_end事件
                return;
            }

            // 创建工具调用显示
            const toolElement = this.createToolCallElement(output.lastToolCall, timestamp, stepId);
            this.addElementToChat(toolElement);

            // 处理工具执行
            this.handleToolCall(output.lastToolCall, stepId);

            // 如果同时有toolResult，直接显示结果
            if (output.toolResult) {
                this.displayToolResult(output.toolResult, stepId, output.toolName);
            }
        } else if (step === 'tools' && output.toolResult) {
            // 显示工具结果 - 找到最近的工具调用步骤并更新
            this.displayToolResultToLatest(output.toolResult, output.toolName);
        } else {
            // 其他步骤的显示
            const stepElement = this.createStepElement(step, output, timestamp, stepId);
            this.addElementToChat(stepElement);
        }

        this.updateStatus(`执行步骤: ${this.getStepDisplayName(step)}`, 'connecting');
    }
    createStepElement(step, output, timestamp, stepId) {
        const stepDiv = document.createElement('div');
        stepDiv.className = 'agent-step';
        stepDiv.id = stepId;
        const header = document.createElement('div');
        header.className = 'step-header';
        header.textContent = `🤖 ${this.getStepDisplayName(step)}`;
        header.onclick = () => this.toggleStepContent(stepId);
        const content = document.createElement('div');
        content.className = 'step-content';
        content.innerHTML = `
            <div class="tool-call">
                <div class="tool-name">Step: ${step}</div>
                <pre>${JSON.stringify(output, null, 2)}</pre>
                <div class="timestamp">${new Date(timestamp).toLocaleString()}</div>
            </div>
        `;
        stepDiv.appendChild(header);
        stepDiv.appendChild(content);
        return stepDiv;
    }
    getStepDisplayName(step) {
        const stepNames = {
            'action': '分析动作',
            'check': '检查结果',
            'tools': '执行工具',
            'error': '错误处理'
        };
        return stepNames[step] || step;
    }

    getToolDisplayName(toolName) {
        const toolNames = {
            'api-doc-search': '🔍 搜索SpreadJS文档',
            'execute-spreadjs': '⚡ 执行SpreadJS代码'
        };
        return toolNames[toolName] || `🔧 ${toolName}`;
    }

    createToolCallElement(toolCall, timestamp, stepId) {
        const { name: toolName, args } = toolCall;

        const toolDiv = document.createElement('div');
        toolDiv.className = 'agent-step';
        toolDiv.id = stepId;

        const header = document.createElement('div');
        header.className = 'step-header';
        header.textContent = this.getToolDisplayName(toolName);
        header.onclick = () => this.toggleStepContent(stepId);

        const content = document.createElement('div');
        content.className = 'step-content';

        // 根据工具类型显示不同内容
        if (toolName === 'api-doc-search') {
            content.innerHTML = `
                <div class="tool-input">
                    <div class="input-label">🔍 搜索关键词：</div>
                    <div class="input-content">${args.keyword}</div>
                </div>
                <div class="tool-status">正在搜索SpreadJS文档...</div>
                <div class="timestamp">${new Date(timestamp).toLocaleString()}</div>
            `;
        } else if (toolName === 'execute-spreadjs') {
            content.innerHTML = `
                <div class="tool-input">
                    <div class="input-label">⚡ 执行代码：</div>
                    <div class="code-block">${args.executionPackage?.executeCode || args.execute_logic || ''}</div>
                </div>
                <div class="tool-input">
                    <div class="input-label">🔍 查询代码：</div>
                    <div class="code-block">${args.executionPackage?.queryCode || args.query_logic || ''}</div>
                </div>
                <div class="tool-status">正在执行SpreadJS代码...</div>
                <div class="timestamp">${new Date(timestamp).toLocaleString()}</div>
            `;
        } else {
            content.innerHTML = `
                <div class="tool-input">
                    <div class="input-label">📝 输入参数：</div>
                    <pre class="input-content">${JSON.stringify(args, null, 2)}</pre>
                </div>
                <div class="tool-status">正在执行...</div>
                <div class="timestamp">${new Date(timestamp).toLocaleString()}</div>
            `;
        }

        toolDiv.appendChild(header);
        toolDiv.appendChild(content);
        return toolDiv;
    }

    displayToolResult(result, stepId, toolName) {
        const stepElement = document.querySelector(`#${stepId}`);
        if (!stepElement) return;

        const content = stepElement.querySelector('.step-content');
        if (!content) return;

        // 移除状态提示，添加结果显示
        const statusElement = content.querySelector('.tool-status');
        if (statusElement) {
            statusElement.remove();
        }

        // 添加输出结果
        const resultDiv = document.createElement('div');
        resultDiv.className = 'tool-output';

        try {
            const parsedResult = typeof result === 'string' ? JSON.parse(result) : result;

            // 根据工具名称和结果格式判断如何显示
            if (toolName === 'api-doc-search' && Array.isArray(parsedResult)) {
                // api-doc-search 的结果
                const resultCount = parsedResult.length;
                resultDiv.innerHTML = `
                    <div class="output-label">📚 搜索结果 (${resultCount} 条)：</div>
                    <div class="search-results">
                        ${parsedResult.slice(0, 3).map((item, index) => `
                            <div class="search-item">
                                <div class="search-title">${index + 1}. ${item.payload?.title || '相关文档'}</div>
                                <div class="search-answer">${item.payload?.answer || ''}</div>
                            </div>
                        `).join('')}
                        ${resultCount > 3 ? `<div class="more-results">...还有 ${resultCount - 3} 条结果</div>` : ''}
                    </div>
                `;
            } else if (toolName === 'execute-spreadjs' || parsedResult.query_result) {
                // execute-spreadjs 的结果
                resultDiv.innerHTML = `
                    <div class="output-label">✅ 执行结果：</div>
                    <div class="result-content success">执行成功！</div>
                    <div class="output-label">📊 查询结果：</div>
                    <div class="result-content">${JSON.stringify(parsedResult.query_result, null, 2)}</div>
                `;
            } else {
                // 其他工具的结果
                resultDiv.innerHTML = `
                    <div class="output-label">📄 执行结果：</div>
                    <div class="result-content">${JSON.stringify(parsedResult, null, 2)}</div>
                `;
            }
        } catch (e) {
            resultDiv.innerHTML = `
                <div class="output-label">📄 执行结果：</div>
                <div class="result-content">${result}</div>
            `;
        }

        content.appendChild(resultDiv);

        // 标记为完成状态
        stepElement.classList.add('completed');
    }
    toggleStepContent(stepId) {
        const content = document.querySelector(`#${stepId} .step-content`);
        if (content) {
            content.classList.toggle('expanded');
        }
    }
    async handleToolCall(toolCall, stepId) {
        const { name: toolName, args } = toolCall;
        if (toolName === 'execute-spreadjs') {
            await this.executeSpreadJSCode(args, stepId);
        }
        else if (toolName === 'api-doc-search') {
            // GCQA search is handled on the server side, just log for now
            console.log('GCQA search executed:', args);
            // 结果会通过toolResult消息来显示
        }
    }
    async executeSpreadJSCode(params, stepId) {
        try {
            const { executionPackage } = params;
            if (!executionPackage) {
                console.error('No execution package provided');
                return;
            }
            const { executeCode, queryCode, id: executionId } = executionPackage;
            this.currentExecutionId = executionId;
            // Execute the SpreadJS code
            console.log('Executing SpreadJS code:', executeCode);
            // Use eval to execute the code (in a real app, use safer alternatives)
            const executeResult = this.safeEval(executeCode);
            // Execute query code to get results
            const queryResult = this.safeEval(queryCode);
            // Send results back to server
            this.sendExecutionResults(executionId, {
                executeSuccess: true,
                executeResult,
                queryResult,
                timestamp: new Date().toISOString()
            });
            // Update the step display with execution results using new display method
            this.displayExecutionResult(stepId, {
                executeSuccess: true,
                queryResult,
                timestamp: new Date().toISOString()
            });
        }
        catch (error) {
            console.error('SpreadJS execution error:', error);
            // Send error back to server
            if (this.currentExecutionId) {
                this.sendExecutionResults(this.currentExecutionId, {
                    executeSuccess: false,
                    error: error instanceof Error ? error.message : 'Unknown error',
                    timestamp: new Date().toISOString()
                });
            }

            // Update UI with error
            this.displayExecutionResult(stepId, {
                executeSuccess: false,
                error: error instanceof Error ? error.message : 'Unknown error',
                timestamp: new Date().toISOString()
            });
        }
    }
    safeEval(code) {
        try {
            // Create a safer execution context
            const func = new Function('GC', 'workbook', `
                ${code}
            `);
            return func(window.GC, window.workbook);
        }
        catch (error) {
            throw new Error(`Code execution failed: ${error}`);
        }
    }
    sendExecutionResults(executionId, results) {
        if (!this.ws || !this.isConnected) {
            return;
        }
        this.ws.send(JSON.stringify({
            type: 'execution_result',
            data: {
                executionId,
                result: results,
                sessionId: this.sessionId
            }
        }));
    }
    updateStepWithResults(stepId, results) {
        const contentElement = document.querySelector(`#${stepId} .step-content`);
        if (contentElement) {
            const resultDiv = document.createElement('div');
            resultDiv.className = 'tool-call';
            resultDiv.innerHTML = `
                <div class="tool-name">执行结果</div>
                <pre>${JSON.stringify(results, null, 2)}</pre>
            `;
            contentElement.appendChild(resultDiv);
        }
    }

    displayExecutionResult(stepId, result) {
        const stepElement = document.querySelector(`#${stepId}`);
        if (!stepElement) return;

        const content = stepElement.querySelector('.step-content');
        if (!content) return;

        // 移除状态提示
        const statusElement = content.querySelector('.tool-status');
        if (statusElement) {
            statusElement.remove();
        }

        // 添加执行结果
        const resultDiv = document.createElement('div');
        resultDiv.className = 'tool-output';

        if (result.executeSuccess) {
            resultDiv.innerHTML = `
                <div class="output-label">✅ 执行结果：</div>
                <div class="result-content success">代码执行成功！</div>
                <div class="output-label">📊 查询结果：</div>
                <div class="result-content">${JSON.stringify(result.queryResult, null, 2)}</div>
            `;
        } else {
            resultDiv.innerHTML = `
                <div class="output-label">❌ 执行失败：</div>
                <div class="result-content error">${result.error}</div>
            `;
        }

        content.appendChild(resultDiv);
        stepElement.classList.add('completed');
    }

    displayToolResultToLatest(result, toolName) {
        // 找到最近的未完成的工具调用步骤
        const allSteps = document.querySelectorAll('.agent-step');
        let latestStep = null;

        // 从后往前找最近的未完成步骤
        for (let i = allSteps.length - 1; i >= 0; i--) {
            const step = allSteps[i];
            if (!step.classList.contains('completed') && step.querySelector('.tool-status')) {
                latestStep = step;
                break;
            }
        }

        if (latestStep) {
            const stepId = latestStep.id;
            this.displayToolResult(result, stepId, toolName);
        } else {
            console.log('未找到可更新的工具调用步骤');
        }
    }

    addMessage(content, type) {
        const messageDiv = document.createElement('div');
        messageDiv.className = `message ${type}-message`;
        const prefix = type === 'user' ? '👤 用户' : '🤖 Agent';
        messageDiv.innerHTML = `<strong>${prefix}:</strong> ${content}`;
        this.addElementToChat(messageDiv);
    }
    addElementToChat(element) {
        const chatMessages = document.getElementById('chatMessages');
        chatMessages.appendChild(element);
        chatMessages.scrollTop = chatMessages.scrollHeight;
    }
}
// Initialize the client when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
    new SpreadJSAgentClient();
});
